﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tao.FreeType;
using AvantGameMachine.FileSystem;

namespace AvantGameMachine.Graphics
{
    public class Font
    {
        private const uint FSize = 512;//ushort.MaxValue;
        private List<FontChar> charTextures = new List<FontChar>();
        private IntPtr pFace;
        private Size2D fs;

        internal Font(IntPtr _pointerFace,uint _sz)
        {
            pFace = _pointerFace;
            FontSizeEqual = _sz;

            LoadChars();
        }

        public Size2D FontSize
        {
            get
            {
                return fs;
            }

            set
            {
                FT.FT_Set_Pixel_Sizes(pFace, (uint)value.Width, (uint)value.Height);
                fs = new Size2D(value.Width, value.Height);
            }
        }

        public uint FontSizeEqual
        {
            set
            {
                FT.FT_Set_Pixel_Sizes(pFace, value, 0);
                fs = new Size2D(value, value);
            }
        }

        internal void LoadChars()
        {
            for (uint i=0;i<FSize;i++)
            {
                LoadCharTexture(i);
            }
        }

        internal FontChar GetChar(char _ch)
        {
            return charTextures[_ch];
        }

        internal void LoadCharTexture(uint _charCode)
        {
	        if(FT.FT_Load_Glyph( pFace, FT.FT_Get_Char_Index( pFace, _charCode ), FT.FT_LOAD_DEFAULT ) != 0)
                return;

            unsafe
            {
                FT_GlyphSlotRec glyph = *Glyph;
                FT.FT_Render_Glyph(ref glyph, FT_Render_Mode.FT_RENDER_MODE_NORMAL);
                Texture t = new Texture(ref glyph.bitmap);
                FontChar fc = new FontChar(_charCode, this, t,ref glyph.bitmap,glyph);
                charTextures.Add(fc);
            }
        }

        unsafe internal FT_FaceRec* Face
        {
            get
            {
                return (FT_FaceRec*)pFace.ToPointer();
            }
        }

        unsafe internal FT_GlyphSlotRec *Glyph
        {
            get
            {
                return (FT_GlyphSlotRec*)Face->glyph.ToPointer();
            }
        }

        unsafe internal FT_Bitmap Bitmap
        {
            get
            {
                return (FT_Bitmap)Glyph->bitmap;
            }
        }
    }
}
